package hibernate.method;

import hibernate.method.interfaces.EventMethodsInterface;
import hibernate.model.EventParticipating;
import hibernate.model.EventsResult;
import hibernate.model.Reservation;
import hibernate.model.User;
import hibernate.model.UserEvent;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.LogicalExpression;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

public class EventMethods implements EventMethodsInterface{

//	@Override
//	public List<Reservation> listReservationsByLocalAndUserOrAnonim(
//			SessionFactory sessionFactory, Session session, int local_id,
//			int user_id) {
//		Criteria cr = session.createCriteria(Reservation.class);
//		Criterion local = Restrictions.eq("local_id", local_id);
//		Criterion user = Restrictions.eq("user_id", user_id);
//		Criterion anonim = Restrictions.like("user_id", "");
//		
//		LogicalExpression orExp = Restrictions.or(user, anonim);
//	
//		LogicalExpression andExp = Restrictions.and(local, orExp);
//		cr.add(andExp);
//		
//		
//		return cr.list();
//	}

	@Override
	public List<Reservation> listAllReservations(SessionFactory sessionFactory,
			Session session) {
		Criteria cr = session.createCriteria(Reservation.class);
		cr.addOrder(Order.asc("start_date"));
		@SuppressWarnings("unchecked")
		List<Reservation> clist = cr.list();
		return clist;
	}

	@Override
	public void addEvent(SessionFactory sessionFactory, Session session,
			String name, int local_id, int user_id,	String poczatek, String koniec, String opis, Boolean multiple) {
		UserEvent ue = new UserEvent();
		ue.setDescription(opis);
		ue.setEnd(koniec);
		ue.setEventname(name);
		ue.setLocal_id(local_id);
//		if(reservation_id == null)  ue.setReservation_id(null);
//		else ue.setReservation_id(reservation_id);
		ue.setStart(poczatek);
		ue.setUser_id(user_id);
		ue.setMultiple(multiple);

		session.save(ue);
		
	}

	@Override
	public void deleteEvent(SessionFactory sessionFactory, Session session,
			UserEvent ue) {
		session.delete(ue);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Reservation> listByUser(SessionFactory sessionFactory,
			Session session, int user_id) {
		Criteria cr = session.createCriteria(Reservation.class);
		cr.add(Restrictions.eq("user_id", user_id));
		return cr.list();
	}

	@Override
	public void addEventPatricipating(SessionFactory sessionFactory,
			Session session, int event_id, int user_id, Boolean maybe) {
		EventParticipating ep = new EventParticipating();
		ep.setEvent_id(event_id);
		ep.setUser_id(user_id);
		ep.setMaybe(maybe);
		session.save(ep);
		
	}

	@Override
	public void deleteParticipating(SessionFactory sessionFactory,
			Session session, EventParticipating ep) {
		session.delete(ep);
		
	}

	@Override
	public void checkIfMaybe(SessionFactory sessionFactory, Session session,
			EventParticipating ep, Boolean maybe) {
		ep.setMaybe(maybe);
		session.save(ep);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<EventParticipating> findByUserEvent(
			SessionFactory sessionFactory, Session session, int user_id,
			int event_id) {
		Criteria cr = session.createCriteria(EventParticipating.class);
		Criterion user = Restrictions.eq("user_id", user_id);
		Criterion event = Restrictions.eq("event_id",event_id);
	
		LogicalExpression andExp = Restrictions.and(user, event);
		cr.add(andExp);
		
		return cr.list();
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<User> listUsersParticipatingForSure(
			SessionFactory sessionFactory, Session session, int event_id) {
		Criteria cr = session.createCriteria(EventParticipating.class);
		Criterion maybe = Restrictions.eq("maybe", false);
		Criterion event = Restrictions.eq("event_id",event_id);
	
		LogicalExpression andExp = Restrictions.and(maybe, event);
		cr.add(andExp);
		
		UserMethods um = new UserMethods();
		List<EventParticipating> ep = new ArrayList<EventParticipating>(cr.list());
		List<User> u = new ArrayList<User>();
		for (EventParticipating e:ep){
			u.add(um.id_to_user(sessionFactory, session, e.getUser_id()));
		}
		
		return u;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<User> listUsersParticipatingMaybe(
			SessionFactory sessionFactory, Session session, int event_id) {
		Criteria cr = session.createCriteria(EventParticipating.class);
		Criterion maybe = Restrictions.eq("maybe", true);
		Criterion event = Restrictions.eq("event_id",event_id);
	
		LogicalExpression andExp = Restrictions.and(maybe, event);
		cr.add(andExp);
		
		UserMethods um = new UserMethods();
		List<EventParticipating> ep = new ArrayList<EventParticipating>(cr.list());
		List<User> u = new ArrayList<User>();
		for (EventParticipating e:ep){
			u.add(um.id_to_user(sessionFactory, session, e.getUser_id()));
		}
		
		
		return u;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<EventParticipating> listParticipatingByUser(
			SessionFactory sessionFactory, Session session, int user_id) {
		Criteria cr = session.createCriteria(EventParticipating.class);
		cr.add(Restrictions.eq("user_id", user_id));
		return cr.list();
	}

	@Override
	public EventParticipating idToEventParticipating(
			SessionFactory sessionFactory, Session session, int participating_id) {
		EventParticipating ep = (EventParticipating) session.get(EventParticipating.class, new Integer(participating_id));
		return ep;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<UserEvent> findUserEventById(SessionFactory sesionFactory,
			Session session, int userEventId) {
		Criteria cr = session.createCriteria(UserEvent.class);
		cr.add(Restrictions.eq("id", userEventId));
		return cr.list();
	}

	@Override
	public int CountAllPatricipians(SessionFactory sessionFactory,
			Session session, int event_id) {
		Criteria cr = session.createCriteria(EventParticipating.class);
		cr.add(Restrictions.eq("event_id", event_id));
		return ((Number)cr.setProjection(Projections.rowCount()).uniqueResult()).intValue();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<UserEvent> listOrganizingByUser(
			SessionFactory sessionFactory, Session session, int user_id) {
		Criteria cr = session.createCriteria(UserEvent.class);
		cr.add(Restrictions.eq("user_id", user_id));
		return cr.list();
	}

	@Override
	public List<UserEvent> listAllUserEvents(SessionFactory sessionFactory,
			Session session) {
		Criteria cr = session.createCriteria(UserEvent.class);
		cr.addOrder(Order.asc("start"));
		@SuppressWarnings("unchecked")
		List<UserEvent> clist = cr.list();
		return clist;
	}

	@Override
	public int countAllReservations(SessionFactory sessionFactory,
			Session session) {
		Criteria cr = session.createCriteria(Reservation.class);
	//cr.add(Restrictions.eq("event_id", event_id));
		return ((Number)cr.setProjection(Projections.rowCount()).uniqueResult()).intValue();
	}

	@Override
	public int countReservationsByLocal(SessionFactory sessionFactory,
			Session session, int local_id) {
		Criteria cr = session.createCriteria(Reservation.class);
		cr.add(Restrictions.eq("local_id", local_id));
			return ((Number)cr.setProjection(Projections.rowCount()).uniqueResult()).intValue();
	}

	@Override
	public void addEventResult(SessionFactory sessionFactory, Session session,
			int event_id, int game_id, int user_id, String result) {
		EventsResult er = new EventsResult();
		er.setEvent_id(event_id);
		er.setGame_id(game_id);
		er.setResult(result);
		er.setUser_id(user_id);
		session.save(er);
	}

	@Override
	public void deleteEventResult(SessionFactory sessionFactory,
			Session session, EventsResult er) {
		session.delete(er);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<UserEvent> listUserEventByLocal(SessionFactory sessionFactory,
			Session session, int local_id) {
		Criteria cr = session.createCriteria(UserEvent.class);
		cr.add(Restrictions.eq("local_id", local_id));
		return cr.list();
	}

}
